part of dartendo;

class ScaleStatics {
  int brightenShift = 0;
  int brightenShiftMask = 0;
  int brightenCutoffMask = 0;
  int darkenShift = 0;
  int darkenShiftMask = 0;

  void setFilterParams(int darkenDepth, int brightenDepth) {
    switch (darkenDepth) {
      case 0:
                darkenShift = 0;
                darkenShiftMask = 0x00000000;
                break;
      case 1:
                darkenShift = 4;
                darkenShiftMask = 0x000F0F0F;
                break;
      case 2:
                darkenShift = 3;
                darkenShiftMask = 0x001F1F1F;
                break;
      case 3:
                darkenShift = 2;
                darkenShiftMask = 0x003F3F3F;
                break;
      default:
                 darkenShift = 1;
                 darkenShiftMask = 0x007F7F7F;
                 break;
    }

    switch (brightenDepth) {
      case 0:
                brightenShift = 0;
                brightenShiftMask = 0x00000000;
                brightenCutoffMask = 0x00000000;
                break;
      case 1:
                brightenShift = 4;
                brightenShiftMask = 0x000F0F0F;
                brightenCutoffMask = 0x003F3F3F;
                break;
      case 2:
                brightenShift = 3;
                brightenShiftMask = 0x001F1F1F;
                brightenCutoffMask = 0x003F3F3F;
                break;
      case 3:
                brightenShift = 2;
                brightenShiftMask = 0x003F3F3F;
                brightenCutoffMask = 0x007F7F7F;
                break;
      default:
                 brightenShift = 1;
                 brightenShiftMask = 0x007F7F7F;
                 brightenCutoffMask = 0x007F7F7F;
                 break;
    }
  }

  void doScanlineScaling(List<int> src, List<int> dest, List<bool> changed) {
    int di = 0;
    int di2 = 512;
    int max;

    for (int y = 0; y < 240; y++) {
      if (changed[y]) {
        max = (y + 1) << 8;
        for (int si = y << 8; si < max; si++) {

          // get pixel value:
          var val = src[si];

          // fill the two pixels on the current scanline:
          dest[di] = val;
          dest[++di] = val;

          // darken pixel:
          val -= ((val >> 2) & 0x003F3F3F);

          // fill the two pixels on the next scanline:
          dest[di2] = val;
          dest[++di2] = val;

          //si ++;
          di++;
          di2++;

        }
      } else {
        di += 512;
        di2 += 512;
      }

      // skip one scanline:
      di += 512;
      di2 += 512;
    }
  }

  void doRasterScaling(List<int> src, List<int> dest, List<bool> changed) {
    int di = 0;
    int di2 = 512;

    int max;
    int col1, col2, col3;
    int r, g, b;
    int flag = 0;

    for (int y = 0; y < 240; y++) {
      if (changed[y]) {
        max = (y + 1) << 8;
        for (int si = y << 8; si < max; si++) {

          // get pixel value:
          col1 = src[si];

          // fill the two pixels on the current scanline:
          dest[di] = col1;
          dest[++di] = col1;

          // fill the two pixels on the next scanline:
          dest[di2] = col1;
          dest[++di2] = col1;

          // darken pixel:
          col2 = col1 - ((col1 >> darkenShift) & darkenShiftMask);

          // brighten pixel:
          col3 = col1 +
            ((((0x00FFFFFF - col1) & brightenCutoffMask) >> brightenShift) & brightenShiftMask);

          dest[di + (512 & flag)] = col2;
          dest[di + (512 & flag) - 1] = col2;
          dest[di + 512 & (512 - flag)] = col3;
          flag = 512 - flag;

          di++;
          di2++;

        }
      } else {
        di += 512;
        di2 += 512;
      }

      // skip one scanline:
      di += 512;
      di2 += 512;
    }
  }

  void doNormalScaling(List<int> src, List<int> dest, List<bool> changed) {
    int di = 0;
    int di2 = 512;
    int val, max;

    for (int y = 0; y < 240; y++) {
      if (changed[y]) {
        max = (y + 1) << 8;
        for (int si = y << 8; si < max; si++) {

          // get pixel value:
          val = src[si];

          // fill the two pixels on the current scanline:
          dest[di++] = val;
          dest[di++] = val;

          // fill the two pixels on the next scanline:
          dest[di2++] = val;
          dest[di2++] = val;

        }
      } else {
        di += 512;
        di2 += 512;
      }

      // skip one scanline:
      di += 512;
      di2 += 512;
    }
  }
}
